import 'dart:io';

import 'package:archive/archive.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart' ;
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:mfkb/config/Config.dart';
import 'package:mfkb/service/FunService.dart';
import 'package:mfkb/util/ColorUtil.dart';
import 'package:path_provider/path_provider.dart';
import 'package:toast/toast.dart';
import 'package:webview_flutter/webview_flutter.dart';


class WebViewPlugin extends StatefulWidget {
  String file ;
  String md5 ;
  int type ;

  WebViewPlugin({Key key , @required this.file , @required this.md5 , @required this.type}):super(key : key) ;

  @override
  _WebViewPluginState createState() => _WebViewPluginState();
}

class _WebViewPluginState extends State<WebViewPlugin> {

  bool loading = true ;
  double schedule = 0.0 ;
  String url = "" ;
  bool viewShow = false ;
  double statusBarHeight = 0 ;
  String statusBarColor = "#FFFFFF" ;
  WebViewController _controller ; 
  var statuColor = SystemUiOverlayStyle.dark ;

  @override
  void initState() {
    super.initState();
    // 1. 检查更新
    if(widget.type == 2 && Config().getSpf().getBool(widget.md5) != null){
      FunService().checkUpdate(widget.file).then((value){
        if(value["code"] == 200){
          String md5 = value["data"] ;
          if(md5 != null){
            if(Config().getSpf().getBool(md5) == null){
              downloadFromServer() ;
            }else{
              loadResource() ;
            }
          }else{
            loadResource() ;
          }
        }else{
          loadResource() ;
        }
      }) ;
    }else if(widget.type == 1 && Config().getSpf().getBool(widget.md5) != null){
      FunService().checkNews(widget.file).then((value){
        if(value["code"] == 200){
          String md5 = value["data"] ;
          if(md5 != null){
            if(Config().getSpf().getBool(md5) == null){
              downloadFromServer() ;
            }else{
              loadResource() ;
            }
          }else{
            loadResource() ;
          }
        }else{
          loadResource() ;
        }
      }) ;
    }else{
      downloadFromServer() ;
    }
  }

  loadResource(){
    getExternalStorageDirectory().then((Directory dir) async {
      setState(() {
        schedule = 1 ;
        viewShow = true ;
        url = File(dir.path + "/" + widget.md5 + "/index.html").uri.toString()+"?token="+Config().getToken() ;
      }); 
    }) ;
  }

  downloadFromServer(){
    print("download") ;
    getExternalStorageDirectory().then((Directory dir) async{
      var dire = Directory(dir.path+"/"+widget.md5) ;
      bool dExit = await dire.exists() ;
      if(!dExit){
        await dire.create()  ;
      }
      String fileName = DateTime.now().millisecond.toString() + ".zip" ; 
      Dio dio = new Dio() ;
      Response response = await dio.download(Config().getImgHost() + "/" + widget.file , dir.path+"/"+ fileName , onReceiveProgress: (int sent, int total){ 
        setState(() {
          schedule = sent / total ; 
        });
      }) ;
      if (response.statusCode == 200) {
        // 下载成功后进行解压 
        // 从磁盘读取Zip文件。
        List<int> bytes = File(dir.path + "/" + fileName).readAsBytesSync() ; 
        // 解码Zip文件
        Archive archive = null ;
        try{
          archive = ZipDecoder().decodeBytes(bytes) ;
        } catch(e){ 
          Toast.show("模块异常", context) ;
        }
        // 将Zip存档的内容解压缩到磁盘。 
        for (ArchiveFile file in archive) { 
          if (file.isFile) { 
            List<int> data = file.content ; 
            File(dir.path + "/" + widget.md5+"/"+file.name) 
              ..createSync(recursive: true) 
              ..writeAsBytesSync(data) ;  
          } else { 
            Directory(dir.path + "/" + widget.md5+"/"+file.name) 
              ..createSync(recursive: true) ; 
          }
        }
        setState(() {
          Config().getSpf().setBool(widget.md5, true) ;
          url = File(dir.path + "/" + widget.md5 + "/index.html").uri.toString()+"?token="+Config().getToken() ;
          viewShow = true ;
        });
      }else{
        Directory(dir.path + "/" + widget.md5).delete() ;
        Toast.show("网络错误", context) ;
      }
    }) ;
  }

  @override
  Widget build(BuildContext context) {
    statusBarHeight = MediaQuery.of(context).padding.top ;
    return AnnotatedRegion<SystemUiOverlayStyle>(
      value: statuColor ,
      child: WillPopScope(
        child: Scaffold(
          body: Container(
            color: Color.fromARGB(255, 236, 237, 241),
            child: Stack(
              children: <Widget>[
                Visibility(
                  visible: viewShow ,
                  child: Container(
                    width: ScreenUtil().setWidth(375),
                    height: ScreenUtil().setHeight(812),
                    child: Column(
                      children: <Widget>[
                        Container(
                          height: statusBarHeight ,
                          color: ColorUtil().hexColor(statusBarColor),
                        ) ,
                        Expanded(
                          child: WebView(
                            initialUrl: url ,
                            javascriptMode: JavascriptMode.unrestricted,
                            onWebViewCreated: (WebViewController controller){
                              _controller = controller ;
                              setState(() {
                                loading = false ;
                              });
                            },
                            onPageFinished: (a){
                              
                            },
                            javascriptChannels: <JavascriptChannel>[
                              JavascriptChannel(
                                name: 'statusBar',
                                onMessageReceived: (JavascriptMessage message) {
                                  if(message.message == "hidden"){
                                    setState(() {
                                      statusBarHeight = 0 ;
                                    });
                                  }else if(message.message == "light"){
                                    setState(() {
                                      statuColor = SystemUiOverlayStyle.light ;
                                    });
                                  }else if(message.message == "dark"){
                                    statuColor = SystemUiOverlayStyle.dark ;
                                  }else{
                                    setState(() {
                                      statusBarColor = message.message ;
                                    });
                                  }
                                }
                              ) ,
                              JavascriptChannel(
                                name: 'mfkb_back' ,
                                onMessageReceived: (JavascriptMessage message) {
                                  Navigator.of(context).pop() ;
                                }
                              )
                            ].toSet(),
                          ),
                        )
                      ],
                    ),
                  ) ,
                ) ,
                Visibility(
                  visible: loading ,
                  child: Container(
                    width: ScreenUtil().setWidth(375),
                    height: ScreenUtil().setHeight(812),
                    color: Color.fromARGB(255, 236, 237, 241),
                    child: Center(
                      child: Container(
                        height: 70 ,
                        child: Column(
                          children: <Widget>[
                            SizedBox(
                              child: CircularProgressIndicator(
                                value: schedule ,
                                backgroundColor: Colors.grey.withOpacity(0.2) ,
                                valueColor: AlwaysStoppedAnimation(Colors.grey) ,
                              ),
                              height: 44.0,
                              width: 44.0,
                            ) ,
                            Container(
                              height: 14,
                              margin: EdgeInsets.only(top:ScreenUtil().setHeight(12)),
                              child: Text(
                                "进度" + ((schedule*100).floor()).toString() + "%" ,
                                style: TextStyle(
                                  fontSize: ScreenUtil().setSp(12) ,
                                  height: 14 / ScreenUtil().setSp(12) ,
                                  color: Colors.green 
                                ),
                              ),
                            )
                          ],
                        ),
                      ),
                    ),
                  ) ,
                )
              ],
            ),
          ),
        ),
        onWillPop: () async{
          if(_controller == null){
            return true ;
          }else{
            bool canBack = await _controller.canGoBack() ;
            if(canBack){
              _controller.goBack() ;
            }else{
              return true ;
            }
          }
        },
      ) ,
    );
  }
}